package git.bds.nyc.applet.api.service.demand;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import git.bds.nyc.communal.mapper.mp.AddressMapper;
import git.bds.nyc.communal.model.domain.Address;
import git.bds.nyc.communal.service.audit.AuditFarmerDemandService;
import git.bds.nyc.demand.convert.DemandCovert;
import git.bds.nyc.demand.mapper.ee.DemandEsMapper;
import git.bds.nyc.demand.mapper.mp.CorpDemandMapper;
import git.bds.nyc.demand.mapper.mp.FarmerDemandMapper;
import git.bds.nyc.demand.model.domain.CorpDemand;
import git.bds.nyc.demand.model.domain.FarmerDemand;
import git.bds.nyc.demand.model.dto.DemandAddDTO;
import git.bds.nyc.demand.model.dto.DemandDTO;
import git.bds.nyc.demand.model.dto.DemandInfoDTO;
import git.bds.nyc.demand.model.dto.DemandModifyDTO;
import git.bds.nyc.demand.model.ee.DemandEs;
import git.bds.nyc.enums.AuditType;
import git.bds.nyc.enums.DemandType;
import git.bds.nyc.enums.RoleType;
import git.bds.nyc.exception.BusinessException;
import git.bds.nyc.framework.file.minio.MinioConfig;
import git.bds.nyc.framework.file.minio.MinioUtil;
import git.bds.nyc.page.PageParam;
import git.bds.nyc.page.PageResult;
import git.bds.nyc.result.ResultCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author 成大事
 * @since 2023/2/16 21:37
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class DemandServiceImpl implements DemandService {

    private final CorpDemandMapper corpDemandMapper;

    private final FarmerDemandMapper farmerDemandMapper;

    private final DemandEsMapper demandEsMapper;

    private final AuditFarmerDemandService auditFarmerDemandService;

    private final MinioUtil minioUtil;

    private final MinioConfig minioConfig;

    private  final  AddressMapper addressMapper;



    /**
     * 根据需求id获取需求的详细数据集
     *
     * @param id 需求id
     * @return {@link DemandInfoDTO}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public DemandInfoDTO getCorpDemandInfoById(Long id) {
        return corpDemandMapper.selectJoinOne(DemandInfoDTO.class,
                new MPJQueryWrapper<CorpDemand>()
                        .select(CorpDemand.class,i->!i.getColumn().equals(CorpDemand.USER_ID))
                        .eq(CorpDemand.ID,id)
        );
    }

    /**
     * 通过id获取农民需求信息
     *
     * @param id 身份证
     * @return {@link DemandInfoDTO}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public DemandInfoDTO getFarmerDemandInfoById(Long id) {
        return farmerDemandMapper.selectJoinOne(DemandInfoDTO.class,
                new MPJQueryWrapper<FarmerDemand>()
                        .select(FarmerDemand.class,i->!i.getColumn().equals(CorpDemand.USER_ID))
                        .eq(FarmerDemand.ID,id)
        );
    }

    /**
     * 发布需求
     *
     * @param demandAddDTO 需求操作数据
     * @return {@link Boolean}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean releaseDemand(DemandAddDTO demandAddDTO) {
        long userId = StpUtil.getLoginIdAsLong();
        List<String> roleList = StpUtil.getRoleList();
        Address address = addressMapper.selectOne(new LambdaQueryWrapper<Address>()
                .select(Address::getDetailedAddress, Address::getLocation)
                .eq(Address::getId, demandAddDTO.getContactInfoId()));
        if(roleList.contains(RoleType.FARMER.getMsg())){
            FarmerDemand demand = DemandCovert.INSTANCE.toFarmerDemandForAdd(demandAddDTO, userId);
            farmerDemandMapper.insert(demand);
            String detailedAddress = address.getLocation() + address.getDetailedAddress();
            DemandEs demandEs = DemandCovert.INSTANCE.toDemandEs(demand, detailedAddress,DemandType.FARMER_DEMAND.getValue());
            demandEsMapper.insert(demandEs);
        }else if(roleList.contains(RoleType.COOP.getMsg())){
            CorpDemand demand = DemandCovert.INSTANCE.toCorpDemandForAdd(demandAddDTO, userId);
            corpDemandMapper.insert(demand);
            String detailedAddress = address.getLocation() + address.getDetailedAddress();
            DemandEs demandEs = DemandCovert.INSTANCE.toDemandEs(demand, detailedAddress,DemandType.CORP_DEMAND.getValue());
            demandEsMapper.insert(demandEs);
        }else {
            throw new BusinessException(ResultCode.NOT_ROLE.getCode(),ResultCode.NOT_ROLE.getMessage());
        }
        return true;
    }

    /**
     * 修改需求信息
     *
     * @param demandModifyDTO 需求更改dto
     * @return {@link Boolean}
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean modifyDemandInfo(DemandModifyDTO demandModifyDTO) {
        FarmerDemand farmerDemand = farmerDemandMapper.selectOne(new LambdaQueryWrapper<FarmerDemand>()
                .select(FarmerDemand::getDemandCover)
                .eq(FarmerDemand::getId,demandModifyDTO.getId()));
        if(farmerDemand == null){
            throw new BusinessException(ResultCode.NOT_EXIST.getCode(),ResultCode.NOT_EXIST.getMessage());
        }
        if(!farmerDemand.getDemandCover().equals(demandModifyDTO.getDemandCover())){
            minioUtil.removeFile(minioConfig.getBucketName(),farmerDemand.getDemandCover());
        }
        FarmerDemand demand = DemandCovert.INSTANCE.toFarmerDemandForModify(demandModifyDTO, StpUtil.getLoginIdAsLong());
        return farmerDemandMapper.updateById(demand) > 0;
    }

    /**
     * 根据id删除需求数据
     *
     * @param id 需求id
     * @return {@link Boolean}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delDemandById(Long id) {
        FarmerDemand farmerDemand = farmerDemandMapper.selectOne(new LambdaQueryWrapper<FarmerDemand>()
                .select(FarmerDemand::getDemandCover, FarmerDemand::getAuditStatus)
                .eq(FarmerDemand::getId, id));
        if(farmerDemand == null){
            throw new BusinessException(ResultCode.NOT_EXIST.getCode(),ResultCode.NOT_EXIST.getMessage());
        }
        if(farmerDemand.getAuditStatus().equals(AuditType.PASS.getValue())){
            demandEsMapper.deleteById(id);
        }
        minioUtil.removeFile(minioConfig.getBucketName(),farmerDemand.getDemandCover());
        return corpDemandMapper.deleteById(id) > 0 &&   auditFarmerDemandService.delDemandById(id);
    }

    /**
     * 按类型获取发布需求页面
     *
     * @param pageParam 页面参数
     * @param type      类型
     * @return {@link PageResult}<{@link DemandDTO}>
     */
    @Override
    public PageResult<DemandDTO> getReleaseDemandPageByType(PageParam pageParam, int type) {
        IPage<DemandDTO> page = farmerDemandMapper.selectJoinPage(new Page<>(pageParam.getPageNo(), pageParam.getPageSize()),
                DemandDTO.class,
                new MPJLambdaWrapper<FarmerDemand>()
                        .select(
                                FarmerDemand::getId,
                                FarmerDemand::getDemandSpecies,
                                FarmerDemand::getDemandVariety,
                                FarmerDemand::getDemandWeight,
                                FarmerDemand::getDemandPrice,
                                FarmerDemand::getDemandCover,
                                FarmerDemand::getCreateTime
                        )
                        .eq(FarmerDemand::getAuditStatus, type)
                        .orderByDesc(FarmerDemand::getCreateTime));
        return new PageResult<>(page.getRecords(),page.getTotal());
    }
}
